# encoding: utf-8
import os
import sys
from datetime import datetime, date, timedelta

import django
from django.utils import timezone
from django.db.models import Count

APP_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(APP_DIR)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'traffic.settings')
django.setup()
from core.models import Host, Port, TrafficLog


def distinct(started, ended):
    if started:
        if ended:
            logs = TrafficLog.objects.filter(isvalid=True, date__gte=started, date__lte=ended).order_by('-date')
        else:
            logs = TrafficLog.objects.filter(isvalid=True, date__gte=started).order_by('-date')
    else:
        logs = TrafficLog.objects.all().order_by('-date')
    dgs = logs.values('port_id', 'date').annotate(Count('date'))
    for dict_ in dgs:
        id = dict_.get('port_id')
        da = dict_.get('date')
        dc = dict_.get('date__count')
        if dc > 1:
            print('重复数据 port: {0}  {1} / {2}'.format(id, da, dc))
            plog = logs.filter(port_id=id, date=da).order_by('id')
            plog.exclude(id=plog.first().id).update(isvalid=False)
            min5 = timedelta(seconds=300)
            calc(da - min5, da + min5)


def calc_port(started, ended, ports):
    for port in ports:
        if started:
            if ended:
                logs = port.traffic_logs.filter(isvalid=True, date__gte=started, date__lte=ended).order_by('date')
            else:
                logs = port.traffic_logs.filter(isvalid=True, date__gte=started).order_by('date')
        else:
            logs = port.traffic_logs.filter(isvalid=True).order_by('date')

        length = logs.count()
        print(port.id, port, length)
        for i, cl in enumerate(logs):
            ct = cl.date.minute % 5
            if ct > 0:
                cl.date = cl.date - timedelta(minutes=ct)
                cl.save()
                print('fix id: {0}  date: {1}'.format(cl.id, cl.date.strftime('%Y-%m-%d %H:%M:%S')))
            if i < length - 1:
                pl = logs[i+1]
                pt = pl.date.minute % 5
                if pt > 0:
                    pl.date = pl.date - timedelta(minutes=pt)
                minus = pl.date - cl.date
                seconds = minus.total_seconds()  # + minus.days * 86400
                if seconds > 300: # 补上缺少的采集点
                    print('patch id: {0}  date: {1}  {2}秒'.format(cl.id, cl.date.strftime('%Y-%m-%d %H:%M:%S'), seconds))
                    if seconds <= 259200:
                        in_byte = (pl.traffic_in - cl.traffic_in) / seconds
                        in_bits = in_byte * 8
                        out_byte = (pl.traffic_out - cl.traffic_out) / seconds
                        out_bits = out_byte * 8
                        cl.in_bits = in_bits
                        cl.out_bits = out_bits
                        for i in range(1, int(seconds / 300)):
                            cl.id = None
                            cl.date = cl.date + timedelta(seconds=300)
                            cl.traffic_in = cl.traffic_in + in_byte * 300
                            cl.traffic_out = cl.traffic_out + out_byte * 300
                            cl.save()
                            print('patch date: {0}'.format(cl.date.strftime('%Y-%m-%d %H:%M:%S')))


def calc(started, ended):
    now = timezone.now()
    print(now.strftime('%Y-%m-%d %H:%M:%S'))
    hosts = Host.objects.filter(is_active=True)
    for host in hosts:
        ports = host.ports.all()
        calc_port(started, ended, ports)
    now = timezone.now()
    print(now.strftime('%Y-%m-%d %H:%M:%S'))
    print('ok')


if __name__ == '__main__':
    started = None
    ended = None
    if len(sys.argv) > 1:
        if sys.argv[1] == 'now':
            today = date.today()
            oneday = timedelta(days=1)
            yesterday = (today - oneday).strftime('%Y-%m-%d')
            started, ended = yesterday, yesterday
        elif sys.argv[1].find('/') > 0:
            started = datetime.strptime(sys.argv[1], '%Y-%m-%d/%H:%M:%S')
        else:
            started = datetime.strptime(sys.argv[1], '%Y-%m-%d')
        if len(sys.argv) > 2 and sys.argv[1] != 'now':
            if sys.argv[2].find('/') > 0:
                ended = datetime.strptime(sys.argv[2], '%Y-%m-%d/%H:%M:%S')
            else:
                ended = datetime.strptime(sys.argv[2], '%Y-%m-%d')
        if len(sys.argv) > 3 or (sys.argv[1] == 'now' and len(sys.argv) > 2):
            if sys.argv[3] == 'distinct' or sys.argv[2] == 'distinct':
                distinct(started, ended)
            else:
                if len(sys.argv) > 3:
                    ids = sys.argv[3].split(',')
                else:
                    ids = sys.argv[2].split(',')
                ports = Port.objects.filter(id__in=ids)
                calc_port(started, ended, ports)
        else:
            calc(started, ended)
    else:
        print('usage: {0} <start date | now> [end date] [distinct] [id,id] \n %Y-%m-%d/%H:%M:%S or %Y-%m-%d \n'.format(sys.argv[0]))
